<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>动态组件 & 异步组件</title>
    <script src="../vue.js"></script>
  </head>
  <body>
    <!-- 1 在动态组件上使用 keep-alive -->
    <div id="app1" style="border: 1px dashed blue;margin-bottom: 2px;">
      <!-- keep-alive 标签作用：使失活的组件被缓存！-->
      <keep-alive>
        <component v-bind:is="currentTabComponent"></component>
      </keep-alive>
    </div>
    <!-- 2 异步组件 -->
    <div id="app2" style="border: 1px dashed red;margin-bottom: 2px;">
      <cmt2></cmt2>
    </div>
    <!-- 2.1 处理加载状态 -->
    <div id="app3" style="border: 1px dashed blue;margin-bottom: 2px;">
      <!-- <async-webpack-example></async-webpack-example> -->
    </div>
    <script type="text/javascript">
      // 1 在动态组件上使用 keep-alive
      Vue.component('home', {
        template: `
      		<strong>home component</strong>
      	`
      })
      Vue.component('posts', {
        template: `
      		<strong>posts component</strong>
      	`
      })
      Vue.component('archive', {
        template: `
      		<strong>archive component</strong>
      	`
      })
      var vm1 = new Vue({
        el: '#app1',
        data: {
          // 页面上的当前显示的组件变更为 home
          currentTabComponent: 'home'
        }
      })
      // 页面上的当前显示的组件变更为 posts
      vm1.currentTabComponent = 'posts'
      
      // 2 异步组件
      Vue.component('cmt2', function (resolve, reject) {
          setTimeout(function() {
            // 向 `resolve` 回调传递组件定义
            resolve({
              template: '<div>I am async!</div>'
            })
          }, 1000)
      })
      new Vue({
        el: '#app2'
      })
      
      // 以上是使用了 setTimeout() 延时从服务器获取组件，
      // 另一种推荐的获取组件的方式是将异步组件和 webpack 的 code-splitting 功能一起配合使用
      Vue.component('async-webpack-example', function(resolve) {
        // 这个特殊的 `require` 语法将会告诉 webpack 自动将你的构建代码切割成多个包，这些包会通过 Ajax 请求加载
        require(['./my-async-component', resolve])
      })
      // 你也可以在工厂函数中返回一个 Promise，所以把 webpack 2 和 ES2015 语法加在一起，我们可以这样使用动态导入：
      Vue.component('async-webpack-example2', 
        // 这个动态导入会返回一个 `Promise` 对象
        () => import('./my-async-component')
      )
      // 当使用局部注册的时候，你也可以直接提供一个返回 Promise 的函数：
      new Vue({
        // ...
        components: {
          'my-component': () => import('./my-async-component')
        }
      })

      new Vue({
        el: '#app3'
      })
      
      // 2.1 处理加载状态
      // 这里的异步组件工厂函数也可以返回一个如下格式的对象：
      const AsyncComponent = () => ({
        // 需要加载的组件 (应该是一个 `Promise` 对象)
        component: import('./MyComponent.vue'),
        // 异步组件加载时使用的组件
        loading: LoadingComponent, 
        // 加载失败时使用的组件
        error: ErrorComponent,
        // 展示加载时组件的延时时间。默认值是 200 (毫秒)
        delay: 200,
        // 如果提供了超时时间且组件加载也超时了，则使用加载失败时使用的组件。默认值是：Infinity
        timeout: 1000
      })

    </script>
  </body>
</html>
